#ifndef HTTPLIB_H
#define HTTPLIB_H

#include <vector>
#include <wx/platform.h>
#include <wx/string.h>
#include <wx/url.h>

/* declarations */

namespace httplib
{

class HttpException
{
	public:
		HttpException ( wxString description) : mDescription (description) {};
		~HttpException (){};
		const wxString & getDescription() { return mDescription; }
		void log(std::string);

	private:
		wxString mDescription;
};

class HttpHeader
{
public:
    HttpHeader(const wxString &name, const wxString &value)
        : mName(name), mValue(value) { };
    void setName(const wxString &name) { mName = name; };
    const wxString &getName() const { return mName; };
    void setValue(const wxString &value) { mValue = value; };
    const wxString &getValue() const { return mValue; };
    void writeRaw(std::vector<char> &buffer);

private:
    wxString mName;
    wxString mValue;
};

class HttpMessage
{
    public:
        HttpMessage();
        virtual ~HttpMessage() {};
        void setHeaderValue(const wxString &name, const wxString &value);
        void addHeader(const wxString &name, const wxString &value);
        void setContentType(const wxString &contentType);
        int getHeaderCount() { return mHeaders.size(); };
        const HttpHeader &getHeader(const int index) const;
        const std::vector<char> &getBody() const { return mBody; };
        void writeRaw(std::vector<char> &buffer);
        virtual void writeRawFirstLine(std::vector<char> &buffer) = 0;
        void setBody(const char *data, const int dataSize) { mBody.clear(); mBody.insert(mBody.begin(), data, data + dataSize); };

    protected:
        std::vector<HttpHeader> mHeaders;
        std::vector<char> mBody;
};

class HttpRequest : public HttpMessage
{
    public:
        HttpRequest(const wxURL &url);
        virtual ~HttpRequest() {};
        void setHost(const wxString &host) { mHost = host; };
        void setMethod(const wxString &method) { mMethod = method; };
        void setUrl(const wxURL &url) { mUrl = url; mHost = url.GetServer(); }
        const wxURL &getUrl() const { return mUrl; };
        const wxString &getHost() const { return mHost; };
        const wxString &getMethod() const { return mMethod; };
        void setUserAgent(const wxString &userAgent);

        virtual void writeRawFirstLine(std::vector<char> &buffer);

    private:
        wxString mHost;
        wxString mMethod;
        wxURL mUrl;
};

class HttpResponse : public HttpMessage
{
public:
    HttpResponse() : mStatusCode(0) { };
    virtual ~HttpResponse() {};
    void setStatusCode(const int statusCode) { mStatusCode = statusCode; };
    const int getStatusCode() const { return mStatusCode; };
    virtual void writeRawFirstLine(std::vector<char> &buffer) { };

private:
    int mStatusCode;
};

class HttpLib
{
    wxString mUserAgent;

public:
    HttpResponse *sendRequest(HttpRequest &request);

    HttpLib() : mUserAgent(wxT("HttpLib")) {};

private:

};

}; // namespace

#endif // HTTPLIB_H
